
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.m3g.Appearance;
import javax.microedition.m3g.CompositingMode;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Image2D;
import javax.microedition.m3g.IndexBuffer;
import javax.microedition.m3g.Material;
import javax.microedition.m3g.Texture2D;
import javax.microedition.m3g.Transform;
import javax.microedition.m3g.TriangleStripArray;
import javax.microedition.m3g.VertexArray;
import javax.microedition.m3g.VertexBuffer;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author zinin
 */
public class GameLayer {
    private Transform       iTransform = new Transform();
    private VertexBuffer    iVb;    // positions, normals, colors, texcoords
    private IndexBuffer     iIb;    // indices to iVB, forming triangle strips
    private Appearance      iAppearance; // material, texture, compositing, ...
    private Material        iMaterial = new Material();
    private Image           iImage;
    private final short     KLayerSpan = 5;
    
    public GameLayer(String texImage, int zOrder){
        
        short depth = (short)(KLayerSpan * (1 + zOrder));
        // the array represents a triangle strip for the plane. 
        // 1 * * * * * 0
        //   * *     *
        //   *   *   *
        //   *     * *
        // 3 * * * * * 2
        // The ASCII diagram above represents the vertices in the plane
        short[] vert = {
            10, 10, depth,  -10, 10, depth,   10,-10, depth,  -10,-10, depth}; 

        // create a VertexArray to hold the vertices for the object
        VertexArray vertArray = new VertexArray(vert.length / 3, 3, 2);
        vertArray.set(0, vert.length/3, vert);

        // The per-vertex normals for the plane; these match with the vertices
        // above. Each normal is perpendicular to the surface of the object at
        // the corresponding vertex.
        byte[] norm = {  
            0, 0, 127,    0, 0, 127,    0, 0, 127,    0, 0, 127};

        // create a vertex array for the normals of the object
        VertexArray normArray = new VertexArray(norm.length / 3, 3, 1);
        normArray.set(0, norm.length/3, norm);

        // per vertex texture coordinates
        short[] tex = {  
            1, 0,       0, 0,       1, 1,       0, 1};

        // create a vertex array for the texture coordinates of the object
        VertexArray texArray = new VertexArray(tex.length / 2, 2, 2);
        texArray.set(0, tex.length/2, tex);

        // the length of the triangle strip
        int[] stripLen = { 4 };

        // create the VertexBuffer for our object
        VertexBuffer vb = iVb = new VertexBuffer();
        vb.setPositions(vertArray, 1.0f, null);      // unit scale, zero bias
        vb.setNormals(normArray);
        vb.setTexCoords(0, texArray, 1.0f, null);    // unit scale, zero bias

        // create the index buffer for our object (this tells how to
        // create triangle strips from the contents of the vertex buffer).
        iIb = new TriangleStripArray( 0, stripLen );
        
        try {
            // load the image for the texture
            iImage = Image.createImage( texImage );
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        // create the Image2D (we need this so we can make a Texture2D)
        Image2D image2D = new Image2D( Image2D.RGBA, iImage );

        // create the Texture2D

        // texture color is to be modulated with the lit material color
        Texture2D texture = new Texture2D( image2D );
        texture.setFiltering(Texture2D.FILTER_NEAREST,
                             Texture2D.FILTER_NEAREST);
        texture.setWrapping(Texture2D.WRAP_CLAMP,
                            Texture2D.WRAP_CLAMP);
        texture.setBlending(Texture2D.FUNC_MODULATE);

        // create the appearance
        
        CompositingMode compMode = new CompositingMode();   
//        compMode.setAlphaThreshold(0.01f);
//        compMode.setAlphaWriteEnable(true);
//        compMode.setColorWriteEnable(true);
//        compMode.setDepthWriteEnable(true);
//        compMode.setDepthTestEnable(true);
//        compMode.setDepthOffset((zOrder + 0.5f),1.0f);
        compMode.setBlending(CompositingMode.ALPHA);

        iAppearance = new Appearance();
        iAppearance.setTexture(0, texture);
        iAppearance.setMaterial(iMaterial);
        iAppearance.setCompositingMode(compMode);    
        iMaterial.setColor(Material.DIFFUSE, 0xFFFFFFFF);   // white
        iMaterial.setColor(Material.SPECULAR, 0xFFFFFFFF);  // white
        iMaterial.setShininess(100.0f);
    }
    
    // Render the plane. We provide the vertex and index buffers
    // to specify the geometry; the appearance so we know what
    // material and texture to use; and the transform to tell
    // where to render the object
    public void render(Graphics3D context) {
        context.render(iVb, iIb, iAppearance, iTransform);
    }
}
